home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-04-05 | 54.0 KB | 2,099 lines |
- (Message mh:6)
- Resent: Mon, 25 Mar 91 10:18:38 PST
- Resent: qq11@uxb.liv.ac.uk (Alan Thew)
- Resent: Mon, 18 Mar 91 12:21:43 PST
- Resent: jcohn@nsf.gov (Johnathan Charles Cohn)
- Resent: rjg@sq.com (Bob Gibson)
- Resent: dak@sq.com (David Keldson)
- Resent: sow@cad.luth.se (Sven-Ove Westberg)
- Resent: cenkl@linus.mitre.org (Mike Cenkl)
- Resent: david@scocan.sco.com (David J Fiander)
- Return-Path: jamesp@metolius.WR
- To: luj@ecn.purdue.edu (Jun Lu), jkm@ctt.bellcore.COM (James Mcglashan),
- jmvogtle@gamera.cns.syr.edu (John M Vogtle),
- cks@hawkwind.utcs.toronto.edu (Chris Siebenmann),
- ccw@deakin.OZ.AU (Craig Warren), rr@mips.COM (Robert "Bob" Rodriguez),
- munck@Stars.Reston.Unisys.COM (Bob Munck)
- Cc: jamesp@metolius.WR.TEK.COM (James Perkins)
- Subject: Vmail - version 10/87DAS
- Reply-To: jamesp@metolius.WR.TEK.COM (James T. Perkins)
- X-Mailer: Rand MH 6.6 - Vmail 10/87DAS - Vmailtool V1.14 91/02/27
- Date: Mon, 11 Mar 91 11:37:16 PST
- From: James T Perkins <jamesp@metolius.WR>
- --------
-
-
- Okay, folks, you asked for it. Here it is: the Tektronix Logic
- Analyzers DAS Engineering local hack to Vmail, the user-friendly,
- curses-based, MH-calling mail program. It is useless unless you have MH
- installed and available in your PATH. It works with MH version 5.1 or
- better.
-
- There is a SunView button panel available for vmail, called vmailtool,
- available from me. This helps users who can't remember which keys to
- press on vmail, instead having a layer of menus, buttons, and dialog
- boxes atop vmail. It is written in tooltool, a quick gadget panel
- specification language. Tooltool applications run under both sunview
- and openwindows, but not X11/motif or X11/uwm and their ilk.
-
- ___ ___ ___
- | \ / _ \ / __| James Perkins, jamesp@metolius.wr.tek.com, (503)629-1149
- | |> || |_| |\__ \ Logic Analyzers Division, DAS 9200 Engineering
- |___/ |_| |_||___/ Tektronix, MS 92-725, PO Box 4600, Beaverton, OR 97076
-
- This package is sold by weight, not by volume. Some settling of contents may
- have occurred during shipping and handling.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 3)."
- # Contents: CHANGES MANIFEST Makefile READ_ME choose.c cmds.c defs.h
- # find.c inc.c low.c macro.h page.c refresh.c
- # Wrapped by jamesp@metolius on Mon Mar 11 11:20:04 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f CHANGES -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"CHANGES\"
- else
- echo shar: Extracting \"CHANGES\" \(2828 characters\)
- sed "s/^X//" >CHANGES <<'END_OF_CHANGES'
- X
- X Modifications Summary
- X
- X March 8, 1991
- X
- X James Perkins
- X jamesp@metolius.wr.tek.com
- X
- XThis is a summary of James Perkins' modifications to J. Zobel's 1987
- Xvmail distribution.
- X
- XMakefile
- X added targets: install, Saber, lint, tags, source, shar, depend.
- X added STANDOUT_CLEANUP define.
- X
- Xvmail.1
- X Added new commands, bugs, and history section.
- X
- Xdefs.h
- X added "sig_type" type (SunOS Port)
- X added includes of appropriate std includes.
- X lint cleanup - cast to void everywhere.
- X added memalign() extern for Sparc
- X COMP, FORW, INC, REPL, PAGER, EDITOR, SHELL now relative pathnames.
- X Added BURST, DIST, SORTM defines.
- X Added CRTL_R define.
- X Added externs for new functions.
- X
- Xmacro.h
- X lint cleanup - cast to void everywhere.
- X use of memalign() instead of malloc() for Sparc.
- X
- Xcall.c
- X signal commands now of type "sig_type" (SunOS Port)
- X lint cleanup - cast to void everywhere.
- X execv changed to execvp so user can have personal versions of comp, etc.
- X addstatus warning added where necessary.
- X added burst_item(), dist_item(), sort_folder() function.
- X
- Xchoose.c
- X lint cleanup - cast to void everywhere.
- X
- Xcmds.c
- X signal commands now of type "sig_type" (SunOS Port)
- X lint cleanup - cast to void everywhere.
- X
- Xfind.c
- X lint cleanup - cast to void everywhere.
- X
- Xinc.c
- X lint cleanup - cast to void everywhere.
- X execl changed to execlp so user can have personal versions of inc, etc.
- X
- Xinit.c
- X lint cleanup - cast to void everywhere.
- X signal commands now of type "sig_type" (SunOS Port)
- X added tstp(), tint() externs.
- X added stdout_cleanup, which causes stdout to always be turned off
- X when a child is spawned and waited for. It's a yucky kludge
- X but necessary.
- X
- Xload.c
- X now symlinks to mail folders are permitted, and reallocs are done right.
- X use of memalign() instead of malloc() for Sparc.
- X lint cleanup - cast to void everywhere.
- X file name space compression now done more intelligently.
- X
- Xlow.c
- X putchar now returns status.
- X lint cleanup - cast to void everywhere.
- X
- Xmain.c
- X lint cleanup - cast to void everywhere.
- X sets and recognizes options for -burst, -dist, -sort
- X added new commands to help text.
- X help text length macro now dynamically sized.
- X added new commands 'b', 't', 'S', '^R' to command switch.
- X cast wait argument to type (union wait *)
- X
- Xmove.c
- X lint cleanup - cast to void everywhere.
- X Now removal of only item on last page of folder will send you to
- X the last item on previous page of the folder, if possible.
- X
- Xpage.c
- X lint cleanup - cast to void everywhere.
- X fix bug due to walking off end of folder list when looking for the
- X next/prev folder.
- X
- Xrefresh_folder.c
- X Added new source module, which takes an existing folder and
- X rescans the source listing. Needed for "^R" resync,
- X 'b' burst, and 'S' sortm commands.
- X
- XEND OF SUMMARY
- END_OF_CHANGES
- if test 2828 -ne `wc -c <CHANGES`; then
- echo shar: \"CHANGES\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f MANIFEST -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"MANIFEST\"
- else
- echo shar: Extracting \"MANIFEST\" \(684 characters\)
- sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X CHANGES 1
- X MANIFEST 1 This shipping list
- X Makefile 1
- X READ_ME 1
- X call.c 2
- X choose.c 1
- X cmds.c 1
- X defs.h 1
- X find.c 1
- X inc.c 1
- X init.c 2
- X load.c 3
- X low.c 1
- X macro.h 1
- X main.c 2
- X move.c 2
- X page.c 1
- X refresh.c 1
- X vmail.1 2
- END_OF_MANIFEST
- if test 684 -ne `wc -c <MANIFEST`; then
- echo shar: \"MANIFEST\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(1936 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- X# vmail
- X#
- X# Interactive screen-based mail handler that sits on top of MH.
- X#
- X# Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X#
- X# $Id: Makefile,v 1.13 91/03/11 11:19:26 jamesp Exp $
- X#
- X
- XDESTDIR = /usr/local
- XMANDIR = /usr/manl/man1
- XOWNER = bin
- XGROUP = lclsrc
- X
- XCFILES = call.c choose.c cmds.c find.c inc.c init.c load.c low.c main.c \
- X move.c page.c refresh.c
- X
- XINCLUDES = defs.h macro.h
- X
- XSHARFILES = READ_ME CHANGES vmail.1 Makefile $(CFILES) $(INCLUDES)
- X
- XOBJS = call.o choose.o cmds.o find.o inc.o init.o load.o low.o main.o \
- X move.o page.o refresh.o
- X
- XVERS=\"10/87DAS\"
- X
- X#
- X# Define USDATE for U.S. date format on scan
- X#
- X
- XDEFINES = -DVERSION=$(VERS) -DUSDATE -DSTANDOUT_CLEANUP
- X
- XCFLAGS = -O $(DEFINES)
- X
- XLDFLAGS = -s
- X
- XLINT = lint
- XLFLAGS = $(DEFINES)
- X
- XLIBS = -lcurses -ltermcap
- X
- Xvmail: $(OBJS)
- X $(CC) $(LDFLAGS) -o vmail $(OBJS) $(LIBS)
- X
- XSaber:
- X #load $(CFLAGS) $(CFILES) $(HFILES) $(LIBS) -lc
- X
- Xlint:
- X $(LINT) $(LFLAGS) $(CFILES) $(LIBS)
- X
- Xinstall : $(DESTDIR)/vmail $(MANDIR)/vmail.1
- X
- X$(DESTDIR)/vmail: vmail
- X install -c -o $(OWNER) -g $(GROUP) -m 0751 vmail $(DESTDIR)
- X
- X$(MANDIR)/vmail.1 : vmail.1
- X install -C -c -o $(OWNER) -g $(GROUP) -m 0644 vmail.1 $(MANDIR)
- X
- Xclean:
- X rm -f *.[cho1] core vmail make.out tags
- X
- Xtags: source
- X ctags -w $(CFILES) $(INCLUDES)
- X
- Xvmail.1 READ_ME CHANGES Makefile:
- X $(CO) $(COFLAGS) $@
- X
- Xvmail.man: vmail.1
- X nroff -man $? > $@
- X
- Xsource: $(CFILES) $(INCLUDES)
- X
- Xmakekit: $(SHARFILES)
- X makekit -m $(SHARFILES)
- X
- Xdepend : source
- X maketd $(DEFINES) $(CFILES)
- X
- X# DO NOT DELETE THIS LINE - make maketd DEPENDS ON IT
- X# Dependencies generated at: Thu Oct 15 13:21:02 PDT 1987
- X
- Xcall.o: defs.h macro.h
- Xchoose.o: defs.h macro.h
- Xcmds.o: defs.h macro.h
- Xfind.o: defs.h macro.h
- Xinc.o: defs.h macro.h
- Xinit.o: defs.h macro.h
- Xload.o: defs.h macro.h
- Xlow.o: defs.h macro.h
- Xmain.o: defs.h macro.h
- Xmove.o: defs.h macro.h
- Xpage.o: defs.h macro.h
- X
- X# DO NOT ADD ANYTHING HERE - WILL GO AWAY
- END_OF_Makefile
- if test 1936 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f READ_ME -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"READ_ME\"
- else
- echo shar: Extracting \"READ_ME\" \(4838 characters\)
- sed "s/^X//" >READ_ME <<'END_OF_READ_ME'
- X$Header: /mnts/metolius/home/jamesp/usr/src/vmail/RCS/READ_ME,v 1.1 87/10/15 13:40:18 rogers Exp $
- X
- XVMAIL is copyright (C) J. Zobel, University of Melbourne, October 1987.
- XPermission to copy and modify vmail is given in full, but copies and
- Xmodified copies must contain this copyright notice.
- X
- X vmail is an interactive mail handler that sits on top of MH6.5.
- XBecause vmail updates the MH environment by updating .mh_sequences,
- Xit is not compatible with early versions of MH, although it should
- Xwork with MH5 and possibly MH4.
- X
- X vmail has a number of advantages over raw MH. It is screen-based and
- Xfaster (and more convenient) than the MH show-scan-rmm refile cycle.
- XThe `scan' pages for the specified folders are loaded at start up time;
- Xfurther folders may be loaded at any time. `scan' is replaced by paging
- Xbetween screens of stored information, `show' by a fork() to a pager,
- X`rmm' and `refile' by calls to rename (2). Other features, such as folder
- Xpacking, are also faster, as most of the required information is already
- Xknown to the process. vmail makes it feasible for users to organise and
- Xkeep track of moderate volumes of mail without wasting too much time, and
- Xis very simple to use. It has been in use at Melbourne University Computer
- XScience Department for about six months without any problems, and has
- Xbecome the interface of choice for many users. Users who (being new to
- XUNIX) were introduced to mail with vmail have never tried the MH commands
- Xthemselves, being satisfied with the vmail interface and wanting to avoid
- Xthe plethora of MH functions and usages.
- X
- X
- XTechnical Notes
- X
- X vmail is currently Berkeley specific, in particular use of signal(),
- Xvfork(), ioctl() and union wait. It should work with most versions of MH,
- Xbut makes assumptions about the structure of folders, ie, that a folder is
- Xa directory containing files whose names are numbers (other files are
- Xignored). By default, a .mh_profile is required to specify alternatives
- Xto other defaults such as name of mail directory; the environment variable
- XMH may be used to set an alternative profile. The usual assumptions are
- Xmade about the format of mail items - use of fields (if present) such as
- X"To:", "From:" and so on, but these also should not cause any difficulties.
- X comp, repl and forw are all forked from vmail rather than imitated,
- Xthere being no real time advantage to doing otherwise, but are given by
- Xsingle-letter commands rather than longer commands to a shell. Most MH
- Xoptions as set in the profile are ignored (most are not relevant);
- Xbecause comp, repl, etc are forks rather than built-ins, this is not
- Xreally a problem. The paths for these executables are in defs.h and
- Xmay have to be changed.
- X The most unreliable feature is probably the parsing of inc output in
- Xinc.c, used when `i' is given to incorporate new mail. Because some people
- Xlike to give options to inc in their profile, and because inc was too long
- Xto consider rewriting, the simplest solution was to parse the inc output -
- Xif the format changed this code would break.
- X Some may find the mixture of stdio, curses and ioctl ugly, but it is
- Xreasonably orthogonal - stdio is used when tty is in normal mode, curses
- Xwhen control is required, and ioctl and signal when processes are being
- Xsuspended, woken or forked.
- X
- XMade with "make" (no arguments). If cc does not recognize -k option,
- Xvalue of make variable STACK must be changed. The compiler option
- X-DUSDATE must be set if dates are to be displayed in US format.
- X
- XFiles
- X
- X READ_ME This file.
- X vmail.1 Manual entry.
- X Makefile Version number.
- X
- X defs.h Pathnames, defaults, structs, externs,
- X constants. Some of these will need to be
- X edited, eg locations of MH routines.
- X macro.h Simple functions.
- X
- X call.c Forks to MH functions, editor, shell.
- X choose.c Folder chooser, folder display.
- X cmds.c Assorted commands.
- X find.c Searching through headers for strings.
- X inc.c Handles fork to inc, parsing of inc output.
- X init.c Startup, interrupt handling.
- X load.c Loading of folders/mail from mail directory
- X into internal structures.
- X low.c Some primitive functions.
- X main.c High-level switch.
- X move.c Commands for refile, delete, undo.
- X page.c Commands associated with movement between
- X pages and movement within a page.
- X
- XNB: All source files are formatted with tabstop=4.
- X
- X===============================================================================
- X
- XI would appreciate hearing about bugs/bug fixes/amendments/improvements/
- Xadditions; any correspondence should be sent to
- X
- XUUCP: ...!munnari!mulga!jz
- XARPA: jz%mulga.oz@uunet.uu.net
- XCSNET: jz%mulga.oz@australia
- X
- XAny modifications received will be considered for a future release of
- Xvmail. Of particular interest is SYS V compatibility and modifications
- Xto suit versions of MH to which I have no access.
- END_OF_READ_ME
- if test 4838 -ne `wc -c <READ_ME`; then
- echo shar: \"READ_ME\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f choose.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"choose.c\"
- else
- echo shar: Extracting \"choose.c\" \(6579 characters\)
- sed "s/^X//" >choose.c <<'END_OF_choose.c'
- X#ifndef lint
- Xstatic char *RCS_choose_c = "$Id: choose.c,v 1.2 90/04/23 14:40:52 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- choose.c
- X
- X Tty-based folder selection.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X
- X#define START 10 /* offset from margin of screen */
- X#define RESET() toggle=false, /* left- or right- hand indicator */ \
- X i=FIRST+1, /* initial row */ \
- X j=START, /* initial column */ \
- X f=first /* first folder */
- X
- XWINDOW *chooser = (WINDOW *) NULL;
- X
- X/* --------------------
- X Display folder selection page, read commands to move around page and
- X select folders.
- X-------------------- */
- Xvoid
- Xchoose()
- X{
- X int n, i, j;
- X bool toggle;
- X folder next, f, showing(),
- X first = folders, /* first folder on screen */
- X last; /* folder after last folder on screen */
- X char c, str[LEN], flushin();
- X
- X RESET();
- X if(chooser == (WINDOW *) NULL)
- X chooser = newwin(0, 0, 0, 0);
- X last = showing(first);
- Xrestart:
- X while((c = flushin()) != ' ' && c != 'q') switch(c) {
- X case '\r': /* go to next screen of folder names */
- X case '\n':
- X if(last == (folder) NULL)
- X beep();
- X else {
- X first = last;
- X last = showing(first);
- X RESET();
- X }
- X break;
- X case '\b': /* go back one page of folders */
- X if(first == folders)
- X beep();
- X else {
- X for(i=(lines-FIRST)*2 ; i > FIRST && first->prev != (folder) NULL ; i--, first=first->prev)
- X ;
- X last = showing(first);
- X RESET();
- X }
- X break;
- X case CTRL_L: /* redraw */
- X last = showing(first);
- X break;
- X case 'h': /* move left */
- X if(! toggle) /* already at left */
- X beep();
- X else {
- X next = f;
- X FRST_OF_NAME(next);
- X next = next->prev;
- X if(next == (folder) NULL)
- X beep();
- X else {
- X f = next; j = START; toggle = false;
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X }
- X }
- X break;
- X case 'j': /* move down */
- X if(i+1 >= lines) /* at bottom */
- X beep();
- X else {
- X next = f;
- X for(n=0 ; n < 2 && next != (folder) NULL ; n++) {
- X LAST_OF_NAME(next);
- X next = next->next;
- X }
- X if(next == (folder) NULL)
- X beep();
- X else {
- X i++; f = next;
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X }
- X }
- X break;
- X case 'k': /* move up */
- X if(i <= FIRST+1) /* at top */
- X beep();
- X else {
- X next = f;
- X for(n=0 ; n < 2 && next != (folder) NULL ; n++) {
- X FRST_OF_NAME(next);
- X next = next->prev;
- X }
- X if(next == (folder) NULL)
- X beep();
- X else {
- X i--; f = next;
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X }
- X }
- X break;
- X case 'l': /* move right */
- X if(toggle) /* at right */
- X beep();
- X else {
- X next = f;
- X LAST_OF_NAME(next);
- X next = next->next;
- X if(next == (folder) NULL)
- X beep();
- X else {
- X f = next; j = cols/2; toggle = true;
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X }
- X }
- X break;
- X default:
- X beep();
- X break;
- X }
- X if(c == ' ') { /* attempt to go to folder */
- X if(! f->valid) { /* load folder */
- X mvwaddstr(chooser, FIRST, 0, "Reading mail headers ...");
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X f->valid = true;
- X (void)find_mail(f, false);
- X }
- X if(f->valid == EMPTY) { /* folder is empty */
- X /* Go back to chooser, display "empty" message */
- X (void)sprintf(str, "%s -- folder empty", f->name);
- X if(first == f) /* find new first folder for page */
- X if(f->next != (folder) NULL)
- X first = f->next;
- X else
- X first = folders;
- X last = showing(first);
- X RESET();
- X mvwaddstr(chooser, FIRST, 0, str);
- X (void)wmove(chooser, i, j);
- X (void)wrefresh(chooser);
- X goto restart;
- X }
- X curflr = f;
- X curmail = f->mail;
- X y = FIRST;
- X }
- X display_page();
- X}
- X
- X
- X/* --------------------
- X Show all folder names starting with "start" ending with last folder or
- X when page is full.
- X-------------------- */
- Xfolder
- Xshowing(start)
- X folder start;
- X{
- X int count, i = FIRST+1, j = START;
- X bool toggle = false;
- X folder p, f;
- X item m;
- X char str[LEN];
- X
- X (void)wclear(chooser);
- X mvwaddstr(chooser, TITLE, 0,
- X"h,j,k,l -- left,down,up,right <return>,<bs> -- next/prev page of folders");
- X mvwaddstr(chooser, STATUS, 0,
- X"<space> -- select folder q -- quit, no change ^L -- refresh");
- X for(p=f=start ; i < lines && f != (folder) NULL ; p=f=p->next) {
- X if(f->valid) {
- X /* find last page of folder, count items in folders */
- X for(count=0, p=f ; p->next != (folder) NULL &&
- X p->next->name == f->name ; p=p->next)
- X for(m=p->mail ; m != (item) NULL ; m=m->next, count++)
- X ;
- X for(m=p->mail ; m != (item) NULL ; m=m->next, count++)
- X ;
- X if(count == 1)
- X (void)sprintf(str, "%s: %d, 1 item", f->name, f->mail->number);
- X else
- X (void)sprintf(str, "%s: %d-%d, %d items", f->name, f->mail->number,
- X p->last->number, count);
- X } else
- X (void)sprintf(str, "%-15s(inactive)", f->name);
- X if(f == curflr) standout();
- X mvwaddstr(chooser, i, j, str);
- X if(f == curflr) standend();
- X if(toggle)
- X j = START, i++;
- X else
- X j = cols/2;
- X toggle = ! toggle;
- X }
- X (void)wmove(chooser, FIRST+1, START);
- X (void)wrefresh(chooser);
- X return(f);
- X}
- X
- X
- XWINDOW *folwin = (WINDOW *) NULL;
- X
- X/* --------------------
- X List all folders, active or otherwise.
- X-------------------- */
- Xvoid
- Xlist_folders()
- X{
- X folder f = folders, p;
- X int count, i = FIRST, half = cols/2;
- X bool toggle = false;
- X char str[LEN];
- X WINDOW *newwin();
- X item m;
- X
- X if(folwin == (WINDOW *) NULL)
- X folwin = newwin(0, 0, 0, 0);
- X (void)wclear(folwin);
- X for(p=f ; ; p=f=p->next) {
- X if((i+2) % lines == 0) {
- X if(use_prompt(folwin) == 'q')
- X break;
- X i = FIRST;
- X (void)wclear(folwin);
- X }
- X if(f == (folder) NULL) {
- X (void)use_prompt(folwin);
- X break;
- X }
- X if(f->valid) {
- X /* find last page of folder, count items in folders */
- X for(count=0, p=f ; p->next != (folder) NULL &&
- X p->next->name == f->name ; p=p->next)
- X for(m=p->mail ; m != (item) NULL ; m=m->next, count++)
- X ;
- X for(m=p->mail ; m != (item) NULL ; m=m->next, count++)
- X ;
- X if(count == 1)
- X (void)sprintf(str, "%s: %d, 1 item", f->name, f->mail->number);
- X else
- X (void)sprintf(str, "%s: %d-%d, %d items", f->name, f->mail->number,
- X p->last->number, count);
- X } else
- X (void)sprintf(str, "%-15s(inactive)", f->name);
- X if(f == curflr)
- X (void)wstandout(folwin);
- X if(toggle) {
- X mvwaddstr(folwin, i, half, str);
- X i++;
- X } else
- X mvwaddstr(folwin, i, 10, str);
- X if(f == curflr)
- X (void)wstandend(folwin);
- X toggle = !toggle;
- X }
- X display_page();
- X}
- END_OF_choose.c
- if test 6579 -ne `wc -c <choose.c`; then
- echo shar: \"choose.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f cmds.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"cmds.c\"
- else
- echo shar: Extracting \"cmds.c\" \(3678 characters\)
- sed "s/^X//" >cmds.c <<'END_OF_cmds.c'
- X#ifndef lint
- Xstatic char *RCS_cmds_c = "$Id: cmds.c,v 1.3 90/04/23 14:40:56 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- cmds.c
- X
- X Commands not included in page.c or move.c.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X#include <signal.h>
- X
- X/* --------------------
- X Print the name of the alternate folder.
- X-------------------- */
- Xvoid
- Xshow_folder()
- X{
- X char str[LEN];
- X
- X if(alternate == (folder) NULL)
- X addstatus("No alternate folder", false);
- X else {
- X (void)sprintf(str, "alternate folder is %s\n", alternate->name);
- X addstatus(str, false);
- X }
- X}
- X
- X
- X/* --------------------
- X Make current folder inactive - remove list of mail headers, set valid
- X to false.
- X-------------------- */
- Xvoid
- Xinactive()
- X{
- X folder f, p;
- X
- X /* find first page of folder */
- X p = curflr; FRST_OF_NAME(p);
- X /* find last page of folder */
- X f = curflr; LAST_OF_NAME(f);
- X p->next = f->next;
- X p->valid = false;
- X/* should free records */
- X p->mail = p->last = (item) NULL;
- X p->pagenum = p->pages = 1;
- X if(p->next != (folder) NULL)
- X p->next->prev = p;
- X curflr = p;
- X NEXT_VALID(curflr);
- X if(curflr == (folder) NULL) {
- X curflr = p;
- X PREV_VALID(curflr);
- X }
- X if(curflr == (folder) NULL) {
- X addstatus("Making last active folder inactive", true);
- X to_normal();
- X exit(0);
- X } else {
- X curmail = curflr->mail;
- X y = FIRST;
- X display_page();
- X }
- X}
- X
- X
- X/* --------------------
- X Show current mail item with fork to pager.
- X-------------------- */
- Xvoid
- Xshow_mail()
- X{
- X sig_type (*oldint)(), (*oldquit)(), (*signal())();
- X char str[LEN];
- X union wait status;
- X
- X clear();
- X refresh();
- X top_level = false; /* used by tstp() so that right thing is done
- X when process is restarted */
- X if(! vfork()) {
- X no_control();
- X (void)sprintf(str, "%s/%s/%d", mail_dir, curflr->name, curmail->number);
- X execlp(pager, pager, str, 0);
- X (void)printf("Warning: can't execute %s\n", pager);
- X exit(0);
- X }
- X oldint = signal(SIGINT, SIG_IGN);
- X oldquit = signal(SIGQUIT, SIG_IGN);
- X (void)wait(&status);
- X (void)signal(SIGINT, oldint);
- X (void)signal(SIGQUIT, oldquit);
- X top_level = true;
- X to_control();
- X hold_end(); /* wait for user to want to continue - may wish
- X to read error messages */
- X display_page();
- X}
- X
- X
- X/* --------------------
- X Save current mail item to named file. If first non-space character
- X is ~, expand it.
- X-------------------- */
- Xvoid
- Xsave_item()
- X{
- X struct passwd *pwent, *getpwnam();
- X char *tmp, buf[LEN], *str = buf, save[LEN];
- X FILE *fi, *fo, *fopen();
- X
- X (void)sprintf(save, "%s.%d", curflr->name, curmail->number);
- X (void)sprintf(str, "file (%s)? ", save);
- X get_string(str, str);
- X for(; *str == ' ' ; str++)
- X ;
- X for(tmp=str ; *tmp != '\0' && *tmp != ' ' ; tmp++)
- X ;
- X *tmp = '\0';
- X if(*str != '\0') /* don't take default */
- X if(*str == '~') { /* expand home directory name */
- X tmp = str + 2;
- X if(*(str+1) == '/')
- X pwent = getpwnam(user);
- X else {
- X for( ; *tmp != '\0' && *tmp != '/' ; tmp++)
- X ;
- X *(tmp++) = '\0';
- X if((pwent = getpwnam(str+1)) == (struct passwd *) NULL) {
- X (void)sprintf(save, "%s: no such user", str+1);
- X addstatus(save, true);
- X return;
- X }
- X }
- X (void)sprintf(save, "%s/%s", pwent->pw_dir, tmp);
- X } else /* take str as given */
- X (void)strcpy(save, str);
- X if((fo = fopen(save, "w")) == (FILE *) NULL) {
- X (void)sprintf(str, "%s: no write permission", save);
- X addstatus(str, true);
- X return;
- X }
- X addstatus("saving ...", false);
- X (void)sprintf(str, "%s/%s/%d", mail_dir, curflr->name, curmail->number);
- X fi = fopen(str, "r");
- X while(fgets(str, LEN, fi) != (char *) NULL)
- X (void)fprintf(fo, "%s", str);
- X (void)fclose(fi); (void)fclose(fo);
- X addstatus("saved", false);
- X}
- END_OF_cmds.c
- if test 3678 -ne `wc -c <cmds.c`; then
- echo shar: \"cmds.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f defs.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"defs.h\"
- else
- echo shar: Extracting \"defs.h\" \(4971 characters\)
- sed "s/^X//" >defs.h <<'END_OF_defs.h'
- X#ifndef lint
- Xstatic char *RCS_defs_h = "$Id: defs.h,v 1.8 90/09/19 13:55:10 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- defs.h
- X
- X Interactive screen-based mail handler that sits on top of MH.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#ifdef sun
- X#include <malloc.h>
- Xextern char *memalign();
- X#else
- Xextern char *malloc();
- Xextern char *realloc();
- X#endif
- X#include <pwd.h>
- X#include <setjmp.h>
- X#include <sgtty.h>
- X#include <sys/types.h>
- X#include <sys/wait.h>
- X#include <sys/dir.h>
- X#include <sys/file.h>
- X#include <sys/stat.h>
- X#include <curses.h>
- X
- X/*
- X * MH utilities needed by vmail
- X */
- X#define BURST "burst"
- X#define COMP "comp"
- X#define DIST "dist"
- X#define FORW "forw"
- X#define INC "inc"
- X#define REPL "repl"
- X#define SORTM "sortm"
- X
- X/*
- X * Other things
- X */
- X
- X#if defined(sun) || defined(ultrix)
- X#define sig_type void /* Suns and Ultrix 3.x */
- X#else
- Xtypedef int sig_type; /* the rest of the world */
- X#endif
- X
- X#define PAGER "more" /* default pager */
- X#define EDITOR "vi" /* default editor */
- X#define SHELL "/bin/csh" /* default shell */
- X#define CAT "/bin/cat" /* used as `show' for pipes */
- X
- X#define LEN 255 /* standard string length */
- X#define MAXITEMS 4097 /* number of items in folder */
- X#define FPROT 0755 /* standard file protection */
- X#define TITLE 0 /* title line */
- X#define STATUS 1 /* status line */
- X#define FIRST 2 /* first line of info */
- X#define PROFILE ".mh_profile" /* default profile */
- X#define CURFOL "inbox" /* default current folder */
- X#define CONTEXT "context" /* default context file */
- X#define SEQU ".mh_sequences" /* default .mh_sequences file */
- X#define MAILDIR "Mail" /* default mail directory */
- X
- X#define true 1
- X#define false 0
- X#define EMPTY 2 /* used to mark empty folders */
- X#define CTRL_L '\014'
- X#define CTRL_R '\022'
- X#define ESC '\033'
- X#define DEL '\177'
- X
- X/* --------------------
- X Data structures.
- X
- X Each folder is divided into pages of (_lines_-2) mail items, _lines_
- X being the number of lines for the tty type. Pages of folders are
- X stored in a doubly-linked list of pages (struct mail_folder), mail
- X items (struct mail_item) in doubly liked lists of mail. Folders are
- X sorted alphabetically, and pages of mail items are sorted numerically.
- X-------------------- */
- Xstruct mail_item {
- X int number; /* number of item */
- X char *title; /* header */
- X struct mail_item *next, *prev; /* links to other headers */
- X};
- Xtypedef struct mail_item *item;
- X
- Xstruct mail_folder {
- X char *name; /* folder name */
- X int pages, pagenum; /* no. of pages, no. of page */
- X bool valid; /* true if folder active */
- X item mail, last; /* first and last mail items for page
- X - NULL if folder not active */
- X struct mail_folder *next, *prev; /* linked list of folders */
- X};
- Xtypedef struct mail_folder *folder;
- X
- X
- Xextern folder folders, /* list of all folders */
- X curflr, /* current folder */
- X alternate; /* alternate folder */
- Xextern item curmail; /* current mail */
- Xextern char **environ,
- X *user, /* user name */
- X *pager, /* desired pager */
- X *editor, /* desired editor */
- X *shell, /* desired shell */
- X *mail_dir, /* mail directory */
- X *context; /* context file */
- Xextern int y, /* current Y co-ordinate (for curses) */
- X folder_protect, /* protection for folders */
- X lines, /* lines per screen */
- X cols; /* cols per screen */
- Xextern bool top_level, /* flag used to see if process stopped
- X from within subprocess */
- X do_flush, /* true if input is to be flushed */
- X comp_args, /* true if calls to comp needs args */
- X repl_args, /* true if calls to repl needs args */
- X forw_args, /* true if calls to forw needs args */
- X burst_args, /* true if calls to burst needs args */
- X dist_args, /* true if calls to dist needs args */
- X sort_args; /* true if calls to sortm needs args */
- Xextern jmp_buf env;
- X
- X#include "macro.h"
- X
- Xfolder find_mail();
- Xextern char *sprintf();
- Xvoid add_page_header(), addstatus(), choose(), comp(), create_mail_record(),
- X cursor_down(), cursor_up(),
- X display_page(), delete_item(), deleteline(), edit(),
- X find_folders(), flatten(), forw(), get_env(),
- X get_home(), read_profile(), get_string(), get_title(),
- X goto_folder(), call_shell(), goto_incorp_folder(),
- X goto_next_folder(), goto_prev_folder(), hold_end(),
- X inactive(), inc(), init(), list_folders(),
- X mark_valid_folders(), move_item(), next_page(),
- X no_control(), pack_folder(), prev_page(), repl(),
- X refresh_folder(), save_item(), search(), show_folder(),
- X show_mail(), show_title(), to_control(), to_normal(),
- X undo(), pack(), cursor_first(), cursor_middle(),
- X cursor_last(), goto_first_page(), goto_last_page(),
- X squash(), get_date(), process_args(), do_pipe(),
- X sort_folder(), burst_item(), dist_item();
- Xbool change_item();
- END_OF_defs.h
- if test 4971 -ne `wc -c <defs.h`; then
- echo shar: \"defs.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f find.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"find.c\"
- else
- echo shar: Extracting \"find.c\" \(1985 characters\)
- sed "s/^X//" >find.c <<'END_OF_find.c'
- X#ifndef lint
- Xstatic char *RCS_find_c = "$Id: find.c,v 1.2 90/04/23 14:41:04 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- find.c
- X
- X Searching titles for strings.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X
- Xstatic char str[LEN] = "^.*";
- X
- X/* --------------------
- X Get string for searching, either forwards (forwards = true) or backwards
- X (forwards = false). Then scan mail headers using regex().
- X-------------------- */
- Xvoid
- Xsearch(forwards)
- X int forwards;
- X{
- X char s1[LEN], *s2, *re_comp();
- X int i;
- X bool found = false;
- X folder f;
- X item m;
- X
- X get_string((forwards) ? "/" : "?", s1);
- X if((i = strlen(s1)) > 0) {
- X /* new search string */
- X (void)strcpy(str+3, s1);
- X str[i+=3] = '.', str[++i] = '*', str[++i] = '\0';
- X } else if(strlen(str+3) == 0) {
- X addstatus("", false);
- X return;
- X }
- X if((s2 = re_comp(str)) != (char *) NULL) {
- X addstatus(s2, false);
- X return;
- X }
- X addstatus("searching ...", false);
- X if(forwards)
- X for(i=y+1, f=curflr, m=curmail->next ; ! found && m != curmail ; ) {
- X if(m == (item) NULL) {
- X f = f->next; NEXT_VALID(f);
- X if(f == (folder) NULL) {
- X f = folders;
- X NEXT_VALID(f);
- X }
- X m = f->mail;
- X i = FIRST;
- X }
- X if(! (found = re_exec(m->title)))
- X m = m->next, i++;
- X }
- X else
- X for(i=y-1, f=curflr, m=curmail->prev ; ! found && m != curmail ; ) {
- X if(m == (item) NULL) {
- X f = f->prev; PREV_VALID(f);
- X if(f == (folder) NULL) {
- X /* find last folder */
- X for(f=folders ; f->next != (folder) NULL ; f=f->next)
- X ;
- X PREV_VALID(f);
- X }
- X /* find last mail item with count */
- X for(i=FIRST, m=f->mail ; m->next != (item) NULL ; i++,m=m->next)
- X ;
- X }
- X if(! (found = re_exec(m->title)))
- X m = m->prev, i--;
- X }
- X curmail = m, y = i;
- X if(f != curflr) {
- X curflr = f;
- X display_page();
- X } else if(! found) /* come back to current folder (known to be valid) */
- X addstatus("pattern not found", true);
- X else
- X addstatus("", false);
- X}
- END_OF_find.c
- if test 1985 -ne `wc -c <find.c`; then
- echo shar: \"find.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f inc.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"inc.c\"
- else
- echo shar: Extracting \"inc.c\" \(3762 characters\)
- sed "s/^X//" >inc.c <<'END_OF_inc.c'
- X#ifndef lint
- Xstatic char *RCS_inc_c = "$Id: inc.c,v 1.3 90/04/23 14:41:07 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- inc.c
- X
- X Incorporate new mail with "inc", parse output and update appropriate
- X folder-pages.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X
- X#define INCORP "Incorporating new mail into "
- X#define TAIL "...\n"
- X
- Xstatic folder isfol; /* folder into which mail is being incorporated */
- Xstatic item ismail; /* last item of mail on isfol page */
- Xstatic int count; /* number of items on isfol page */
- X
- X/* --------------------
- X Call, inc, parse output to work out what items have been read and into
- X what folders.
- X-------------------- */
- Xvoid
- Xinc()
- X{
- X char str[LEN], line[LEN], *tmp, *fgets();
- X FILE *pp, *fdopen();
- X int num, pd[2], len = strlen(INCORP), numbers();
- X bool redraw = true;
- X union wait status;
- X
- X addstatus("incorporating mail ... ", true);
- X (void)pipe(pd);
- X if(! vfork()) {
- X (void)close(pd[0]);
- X (void)dup2(pd[1], 1);
- X (void)close(pd[1]);
- X (void)dup2(1, 2);
- X execlp(INC, "inc", 0);
- X }
- X (void)close(pd[1]);
- X if((pp = fdopen(pd[0], "r")) == (FILE *) NULL) {
- X addstatus("panic, can't incorporate mail", true);
- X return;
- X }
- X while((tmp = fgets(str, LEN, pp)) != (char *) NULL) /* read "inc" output */
- X if(strncmp(tmp, INCORP, len) == 0) { /* reading into new folder */
- X tmp += len;
- X tmp[strlen(tmp)-strlen(TAIL)] = '\0';
- X goto_incorp_folder(tmp);
- X if(isfol == (folder) NULL) {
- X (void)sprintf(line, "can't go to folder %s", tmp);
- X addstatus(line, true);
- X redraw = false;
- X break;
- X } else {
- X (void)sprintf(line, "incorporating mail into folder %s", tmp);
- X addstatus(line, true);
- X }
- X } else if(num = numbers(tmp)) /* continuing to read into folder */
- X create_mail_record(num);
- X else if(strlen(str) > 2) { /* vmail is confused - break */
- X str[strlen(str)-1] = '\0';
- X addstatus(str, true);
- X redraw = false;
- X break;
- X }
- X if(redraw) {
- X if(isfol != curflr)
- X alternate = curflr;
- X curflr = isfol;
- X curmail = ismail;
- X y = count;
- X display_page();
- X }
- X (void)fclose(pp);
- X (void)wait(&status);
- X}
- X
- X
- X/* --------------------
- X Extract the first number from str.
- X-------------------- */
- Xint
- Xnumbers(str)
- X char *str;
- X{
- X char save, *tmp;
- X int i;
- X
- X for(; *str == ' ' ; str++)
- X ;
- X for(tmp=str ; *str >= '0' && *str <= '9' ; str++)
- X ;
- X save = *str, *str = '\0', i = atoi(tmp), *str = save;
- X return(i);
- X}
- X
- X
- X/* --------------------
- X Find the folder into which mail is being incorporated, set isfol,
- X ismail, count.
- X-------------------- */
- Xvoid
- Xgoto_incorp_folder(str)
- X char *str;
- X{
- X folder create_folder();
- X
- X GOTO_NAME(isfol, str);
- X if(isfol == (folder) NULL) { /* new folder */
- X isfol = create_folder(str);
- X isfol->valid = true;
- X ismail = (item) NULL;
- X count = FIRST-1;
- X } else {
- X if(! isfol->valid) {
- X isfol->valid = true;
- X (void)find_mail(isfol, false);
- X }
- X /* find last appropriate folder record */
- X LAST_OF_NAME(isfol);
- X for(count=FIRST, ismail=isfol->mail ; ismail->next != (item) NULL ;
- X count++, ismail=ismail->next)
- X ;
- X }
- X}
- X
- X
- X/* --------------------
- X Create and insert new item record into isfol, may need to create new page.
- X-------------------- */
- Xvoid
- Xcreate_mail_record(num)
- X int num;
- X{
- X item m;
- X folder new_folder();
- X
- X m = NEW(mail_item);
- X get_title(isfol, m, num);
- X m->next = (item) NULL;
- X if(count > lines) {
- X /* create new folder record */
- X isfol = new_folder(isfol);
- X ismail = (item) NULL;
- X count = FIRST;
- X } else
- X count++;
- X if(ismail == (item) NULL) {
- X /* new record, possibly new folder */
- X m->prev = (item) NULL;
- X isfol->mail = isfol->last = m;
- X } else {
- X /* insert at end of list of mail items */
- X m->prev = ismail;
- X ismail->next = isfol->last = m;
- X }
- X ismail = m;
- X}
- END_OF_inc.c
- if test 3762 -ne `wc -c <inc.c`; then
- echo shar: \"inc.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f low.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"low.c\"
- else
- echo shar: Extracting \"low.c\" \(3352 characters\)
- sed "s/^X//" >low.c <<'END_OF_low.c'
- X#ifndef lint
- Xstatic char *RCS_low_c = "$Id: low.c,v 1.3 90/04/23 14:41:24 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- low.c
- X
- X Low level screen update and data structure update routines, other
- X similar stuff.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X
- X/* --------------------
- X Get string from terminal (visibly).
- X-------------------- */
- Xvoid
- Xget_string(mes, str)
- X char *mes, *str;
- X{
- X char c;
- X int i;
- X
- X move(STATUS, 0);
- X clrtoeol();
- X addstr(mes);
- X refresh();
- X for(i=0 ; (c = getchar()) != '\n' && c != '\r' && c != ESC ; )
- X if(i > 0 && c == '\b') {
- X i--;
- X mvaddch(STATUS, strlen(mes)+i, ' ');
- X move(STATUS, strlen(mes)+i);
- X refresh();
- X } else if(c != '\b') {
- X str[i++] = c;
- X addch(c);
- X refresh();
- X }
- X str[i] = '\0';
- X move(y, 0);
- X}
- X
- X
- X/* --------------------
- X Put string on status line.
- X-------------------- */
- Xvoid
- Xaddstatus(str, stand)
- X char *str;
- X bool stand;
- X{
- X move(STATUS, 0);
- X clrtoeol();
- X if(stand)
- X standout(); /* doesn't do anything? */
- X addstr(str);
- X if(stand)
- X standend();
- X move(y, 0);
- X refresh();
- X}
- X
- X
- X/* --------------------
- X Fudge deleteline because curses wont delete the line immediately
- X after a ^Z, and because it doesnt clear the last line of the screen.
- X-------------------- */
- Xvoid
- Xdeleteline()
- X{
- X mvaddstr(y, 0, "scribble");
- X deleteln();
- X move(FIRST+lines-1, 0);
- X clrtoeol();
- X move(y, 0);
- X}
- X
- X
- Xint
- Xputch(c)
- X char c;
- X{
- X return(putchar(c)); /* turn macro into routine */
- X}
- X
- X
- X/* --------------------
- X Put prompt on screen, wait for getchar().
- X-------------------- */
- Xint
- Xuse_prompt(win)
- X WINDOW *win;
- X{
- X int c = (cols-42)/2;
- X
- X mvwaddstr(win,FIRST+lines-1,c,"-- hit space to continue, q to quit -- ");
- X (void)wrefresh(win);
- X return(getchar());
- X}
- X
- X
- X/* --------------------
- X Put info for mail item on screen at row i.
- X-------------------- */
- Xvoid
- Xshow_title(str, i, mail)
- X char *str;
- X int i;
- X item mail;
- X{
- X (void)sprintf(str, "%4d%s", mail->number, mail->title);
- X mvaddstr(i, 0, str);
- X}
- X
- X
- X/* --------------------
- X Put header for page at top of screen.
- X-------------------- */
- Xvoid
- Xadd_page_header(str)
- X char *str;
- X{
- X (void)sprintf(str, "%s (page %d of %d) - Type 'h' for help ", curflr->name, curflr->pagenum,
- X curflr->pages);
- X mvaddstr(TITLE, 0, str);
- X}
- X
- X
- X/* --------------------
- X Flush typeahead.
- X-------------------- */
- Xchar
- Xflushin()
- X{
- X struct sgttyb sg;
- X
- X if(do_flush) {
- X (void)ioctl(0, TIOCGETP, (caddr_t)&sg);
- X (void)ioctl(0, TIOCSETP, (caddr_t)&sg);
- X }
- X return(getchar());
- X}
- X
- X
- X/* --------------------
- X Print message, wait for getchar();
- X-------------------- */
- Xvoid
- Xhold_end()
- X{
- X tputs(SO, 1, putch);
- X (void)printf("-- any character to continue --");
- X tputs(SE, 1, putch);
- X (void)fflush(stdout);
- X (void)getchar();
- X}
- X
- X
- X#define ctol(c) (((c) >= 'A' && (c) <= 'Z') ? c-'A'+'a' : c)
- X
- X/* --------------------
- X Case independent strncmp.
- X-------------------- */
- Xlstrncmp(s1, s2, n)
- X char *s1, *s2;
- X int n;
- X{
- X for( ; ctol(*s1) == ctol(*s2) && n > 0 ; s1++, s2++, n--)
- X ;
- X return((n > 0) ? *s1 - *s2 : 0);
- X}
- X
- X
- X/* --------------------
- X String processing - more useful form of index.
- X Skip current non-white then skip white, replacing by null.
- X-------------------- */
- Xchar *
- Xnext_token(t)
- X char *t;
- X{
- X for( ; *t != ' ' && *t != '\t' && *t != '\0' ; t++)
- X ;
- X for( ; *t == ' ' || *t == '\t' ; t++)
- X *t = '\0';
- X return(t);
- X}
- END_OF_low.c
- if test 3352 -ne `wc -c <low.c`; then
- echo shar: \"low.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f macro.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"macro.h\"
- else
- echo shar: Extracting \"macro.h\" \(1229 characters\)
- sed "s/^X//" >macro.h <<'END_OF_macro.h'
- X#ifndef lint
- Xstatic char *RCS_macro_h = "$Id: macro.h,v 1.2 90/04/23 14:41:27 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X macro.h -- assorted functions
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X/*
- X * functions for allocating memory. Note that on sparc implementations,
- X * we use memalign for mallocing structs, as it is less likely to
- X * return a bad pointer.
- X */
- X
- X#define beep() (void)printf("%c", 007)
- X#define NEWSTR(N) (char *) malloc((unsigned)(N))
- X#ifdef sparc
- X#define NEW(S) (struct S *) memalign((unsigned)8,(unsigned)sizeof(struct S))
- X#else
- X#define NEW(S) (struct S *) malloc((unsigned)sizeof(struct S))
- X#endif
- X
- X/* --------------------
- X Moving between pages of mail items.
- X-------------------- */
- X#define PREV_VALID(F) for(; F != (folder) NULL && ! F->valid ; F=F->prev)
- X#define NEXT_VALID(F) for(; F != (folder) NULL && ! F->valid ; F=F->next)
- X#define FRST_OF_NAME(F) for(; F->prev != (folder) NULL && \
- X F->name == F->prev->name ; F=F->prev)
- X#define LAST_OF_NAME(F) for(; F->next != (folder) NULL && \
- X F->name == F->next->name ; F=F->next)
- X#define GOTO_NAME(F,S) for(F=folders ; F != (folder) NULL && \
- X strcmp(S, F->name) != 0 ; F=F->next)
- END_OF_macro.h
- if test 1229 -ne `wc -c <macro.h`; then
- echo shar: \"macro.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f page.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"page.c\"
- else
- echo shar: Extracting \"page.c\" \(8170 characters\)
- sed "s/^X//" >page.c <<'END_OF_page.c'
- X#ifndef lint
- Xstatic char *RCS_page_c = "$Id: page.c,v 1.2 90/04/23 14:41:42 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- page.c
- X
- X Routines for paging between folders.
- X
- X Copyright (C) J. Zobel, University of Melbourne, October 1987.
- X-------------------- */
- X
- X#include "defs.h"
- X
- X/* --------------------
- X Clear screen, show current page of mail items.
- X-------------------- */
- Xvoid
- Xdisplay_page()
- X{
- X int i;
- X item mail;
- X char str[LEN];
- X
- X clear();
- X add_page_header(str);
- X for(i=FIRST, mail=curflr->mail ; mail != (item) NULL ; i++, mail=mail->next)
- X show_title(str, i, mail);
- X move(y, 0);
- X refresh();
- X}
- X
- X
- X/* --------------------
- X Find previous valid page of mail items (times count).
- X-------------------- */
- Xvoid
- Xprev_page(count, display)
- X int count;
- X bool display;
- X{
- X bool show = false;
- X folder f, p = curflr;
- X
- X for( ; count > 0 ; count--) {
- X f = curflr->prev; PREV_VALID(f);
- X if(f == (folder) NULL)
- X break;
- X else {
- X show = true;
- X y = FIRST;
- X curflr = f;
- X curmail = curflr->mail;
- X }
- X }
- X if(p != curflr)
- X alternate = p;
- X if(display) {
- X if(show)
- X display_page();
- X if(f == (folder) NULL)
- X addstatus("first active page", true);
- X }
- X}
- X
- X
- X/* --------------------
- X Find next valid page of mail items (times count).
- X-------------------- */
- Xvoid
- Xnext_page(count, display)
- X int count;
- X bool display;
- X{
- X bool show = false;
- X folder f, p = curflr;
- X
- X for( ; count > 0 ; count--) {
- X f = curflr->next; NEXT_VALID(f);
- X if(f == (folder) NULL)
- X break;
- X else {
- X show = true;
- X y = FIRST;
- X curflr = f;
- X curmail = curflr->mail;
- X }
- X }
- X if(p != curflr)
- X alternate = p;
- X if(display) {
- X if(show)
- X display_page();
- X if(f == (folder) NULL)
- X addstatus("last active page", true);
- X }
- X}
- X
- X
- X/* --------------------
- X Move cursor up count lines.
- X-------------------- */
- Xvoid
- Xcursor_up(count)
- X int count;
- X{
- X bool redraw = false;
- X
- X addstatus("", false); /* clear status line */
- X for( ; count > 0 ; count--)
- X if(curmail->prev == (item) NULL) {
- X if(curflr->prev == (folder) NULL ||
- X curflr->name != curflr->prev->name) {
- X addstatus("first page of folder", true);
- X break;
- X } else {
- X redraw = true;
- X prev_page(1, false);
- X /* find last mail item on page */
- X for( ; curmail->next != (item) NULL ; y++)
- X curmail=curmail->next;
- X }
- X } else {
- X y--;
- X curmail = curmail->prev;
- X }
- X if(redraw)
- X display_page();
- X else {
- X move(y, 0);
- X refresh();
- X }
- X}
- X
- X
- X/* --------------------
- X Move cursor down count lines.
- X-------------------- */
- Xvoid
- Xcursor_down(count)
- X int count;
- X{
- X bool redraw = false;
- X
- X addstatus("", false); /* clear status line */
- X for( ; count > 0 ; count--)
- X if(curmail->next == (item) NULL) {
- X if(curflr->next == (folder) NULL ||
- X curflr->name != curflr->next->name) {
- X addstatus("last page of folder", true);
- X break;
- X } else {
- X redraw = true;
- X next_page(1, false);
- X }
- X } else {
- X y++;
- X curmail = curmail->next;
- X }
- X if(redraw)
- X display_page();
- X else {
- X move(y, 0);
- X refresh();
- X }
- X}
- X
- X
- X/* --------------------
- X Go to next folder, make active if not so already.
- X-------------------- */
- Xvoid
- Xgoto_next_folder(count)
- X int count;
- X{
- X bool changed = false;
- X folder f, p = curflr;
- X
- X for( ; count > 0 ; count--) {
- X /* skip other pages of current folder */
- X for(f=p ; p->next != (folder) NULL && p->next->name == f->name ;
- X p=p->next)
- X ;
- X if(p->next == (folder) NULL) {
- X addstatus("last folder", true);
- X break;
- X } else {
- X changed = true;
- X p = p->next;
- X }
- X }
- X if(changed) {
- X do {
- X if(!p->valid) {
- X p->valid = true;
- X addstatus("reading mail headers ...", true);
- X (void)find_mail(p, false);
- X }
- X if(p->valid == EMPTY)
- X p = p->next;
- X } while(p != (folder) NULL && p->valid != true);
- X if(p == (folder) NULL)
- X addstatus("can't go forward that many folders", true);
- X else {
- X alternate = curflr;
- X curflr = p;
- X curmail = p->mail;
- X y = FIRST;
- X display_page();
- X }
- X }
- X}
- X
- X
- X/* --------------------
- X Goto previous folder, make active if not so already.
- X-------------------- */
- Xvoid
- Xgoto_prev_folder(count)
- X int count;
- X{
- X bool changed = false;
- X folder f, p = curflr;
- X
- X for( ; count > 0 ; count--) {
- X /* skip other pages of current folder */
- X for(f=p ; p->prev != (folder) NULL && p->prev->name == f->name ;
- X p=p->prev)
- X ;
- X if(curflr->prev == (folder) NULL || p->prev == (folder) NULL) {
- X addstatus("first folder", true);
- X break;
- X } else {
- X changed = true;
- X p = p->prev;
- X }
- X }
- X if(changed) {
- X do {
- X if(!p->valid) {
- X p->valid = true;
- X addstatus("reading mail headers ...", true);
- X (void)find_mail(p, false);
- X }
- X if(p->valid == EMPTY)
- X p = p->prev;
- X } while(p != (folder) NULL && p->valid != true);
- X if(p == (folder) NULL)
- X addstatus("can't go back that many folders", true);
- X else {
- X /* skip other pages of current folder */
- X for(f=p ; p->prev != (folder) NULL &&
- X p->prev->name == f->name ; p=p->prev)
- X ;
- X alternate = curflr;
- X curflr = p;
- X curmail = p->mail;
- X y = FIRST;
- X display_page();
- X }
- X }
- X}
- X
- X
- X/* --------------------
- X Make new folder current as specified - read from terminal (get_name =
- X true) or use value in alternate (get_name = false).
- X-------------------- */
- Xvoid
- Xgoto_folder(get_name)
- X bool get_name;
- X{
- X char buf[LEN], *str = buf;
- X folder f;
- X int i;
- X
- X if(get_name || alternate == (folder) NULL) {
- X /* no alternate folder */
- X get_string("folder? ", str);
- X for(i=0 ; *str == ' ' ; i++, str++)
- X ;
- X for(; i < LEN && buf[i] != ' ' && buf[i] != '\0' ; i++)
- X ;
- X if(i < LEN)
- X buf[i] = '\0';
- X GOTO_NAME(f, str);
- X if(f == (folder) NULL) {
- X addstatus("no such folder", true);
- X return;
- X }
- X if(!f->valid) {
- X f->valid = true;
- X addstatus("reading mail headers ...", true);
- X (void)find_mail(f, false);
- X if(f->valid == EMPTY) {
- X (void)sprintf(str, "%s -- folder empty", f->name);
- X addstatus(str, true);
- X return;
- X }
- X }
- X } else
- X f = alternate;
- X if(f == curflr)
- X addstatus("already in that folder", true);
- X else {
- X alternate = curflr;
- X curflr = f;
- X curmail = f->mail;
- X y = FIRST;
- X display_page();
- X }
- X}
- X
- X
- X/* --------------------
- X Go to first line of page, as offset by count.
- X-------------------- */
- Xvoid
- Xcursor_first(count)
- X int count;
- X{
- X item m = curflr->mail;
- X
- X addstatus("", false); /* clear status line */
- X for(y=FIRST ; m != (item) NULL && count > 1 ; count--, y++, m=m->next)
- X ;
- X if(m == (item) NULL)
- X beep();
- X else {
- X curmail = m;
- X move(y, 0);
- X refresh();
- X }
- X}
- X
- X
- X/* --------------------
- X Go to middle line of page.
- X-------------------- */
- Xvoid
- Xcursor_middle()
- X{
- X item m, p;
- X bool tog = false;
- X
- X addstatus("", false); /* clear status line */
- X /* find middle of page - p traverses page at half speed */
- X for(y=FIRST, m=p=curflr->mail ; m != (item) NULL ; m=m->next, tog= !tog)
- X if(tog) {
- X y++;
- X p = p->next;
- X }
- X curmail = p;
- X move(y, 0);
- X refresh();
- X}
- X
- X
- X/* --------------------
- X Go to last line of page, as offset by count.
- X-------------------- */
- Xvoid
- Xcursor_last(count)
- X int count;
- X{
- X item m = curflr->mail;
- X
- X addstatus("", false); /* clear status line */
- X /* find last item, including y-value */
- X for(y=FIRST ; m->next != (item) NULL ; y++, m=m->next)
- X ;
- X for(; m != (item) NULL && count > 1 ; count--, y--, m=m->prev)
- X ;
- X if(m == (item) NULL)
- X beep();
- X else {
- X curmail = m;
- X move(y, 0);
- X refresh();
- X }
- X}
- X
- X
- X/* --------------------
- X Go to first page. ***should use count as offset***
- X-------------------- */
- Xvoid
- Xgoto_first_page()
- X{
- X folder f;
- X
- X f = folders; NEXT_VALID(f);
- X if(f == (folder) NULL) {
- X /* no valid folders - bleah?! */
- X addstatus("no valid folders, exiting", true);
- X to_normal();
- X exit(1);
- X } else if(f != curflr) {
- X alternate = curflr;
- X curflr = f;
- X curmail = f->mail;
- X y = FIRST;
- X display_page();
- X }
- X}
- X
- X
- X/* --------------------
- X Go to last page. ***should use count as offset***
- X-------------------- */
- Xvoid
- Xgoto_last_page()
- X{
- X folder f, p;
- X
- X for(f=folders ; f != (folder) NULL ; f=f->next)
- X if(f->valid)
- X p = f;
- X if(p == (folder) NULL) {
- X /* no valid folders - bleah?! */
- X addstatus("no valid folders, exiting", true);
- X to_normal();
- X exit(1);
- X } else if(p != curflr) {
- X alternate = curflr;
- X curflr = p;
- X curmail = p->mail;
- X y = FIRST;
- X display_page();
- X }
- X}
- END_OF_page.c
- if test 8170 -ne `wc -c <page.c`; then
- echo shar: \"page.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f refresh.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"refresh.c\"
- else
- echo shar: Extracting \"refresh.c\" \(1896 characters\)
- sed "s/^X//" >refresh.c <<'END_OF_refresh.c'
- X#ifndef lint
- Xstatic char *RCS_refresh_folder_c = "$Id: refresh.c,v 1.1 90/09/19 14:00:09 rogers Exp $";
- X#endif
- X
- X/* --------------------
- X vmail -- refresh_folder.c
- X
- X Routine for rescanning a folder.
- X
- X James Perkins 9-19-90 (jamesp@metolius.wr.tek.com)
- X-------------------- */
- X
- X#include "defs.h"
- X
- X/* --------------------
- X Refresh the folder's display - reread the scan listing
- X-------------------- */
- Xvoid
- Xrefresh_folder()
- X{
- X folder f, p;
- X char *curfname = curflr->name;
- X char str[LEN];
- X
- X /*
- X * INACTIVATE CURRENT FOLDER
- X */
- X
- X /* find first, last page of folder */
- X p = curflr; FRST_OF_NAME(p);
- X f = curflr; LAST_OF_NAME(f);
- X
- X /* free (should really, actually free here...) */
- X p->next = f->next;
- X p->valid = false;
- X p->mail = p->last = (item) NULL;
- X p->pagenum = p->pages = 1;
- X if(p->next != (folder) NULL)
- X p->next->prev = p;
- X
- X /* Get new current folder in case the re-scan comes up empty */
- X curflr = p;
- X NEXT_VALID(curflr);
- X if(curflr == (folder) NULL) {
- X curflr = p;
- X PREV_VALID(curflr);
- X }
- X if(curflr == (folder) NULL) {
- X /* Note: just made the last folder inactive ... */
- X }
- X
- X /*
- X * GOTO ORIGINAL, STARTING FOLDER NAME
- X */
- X
- X GOTO_NAME(f, curfname);
- X if(f == (folder) NULL) {
- X addstatus("no such folder", true);
- X return;
- X }
- X if(!f->valid) {
- X f->valid = true;
- X addstatus("re-reading mail headers ...", true);
- X (void)find_mail(f, false);
- X if(f->valid == EMPTY) {
- X /* go to another valid folder (found by code above) */
- X if (curflr == (folder) NULL) {
- X /* No other valid folder to go to! */
- X addstatus("Last active folder is empty", true);
- X to_normal();
- X exit(0);
- X }
- X (void)sprintf(str, "%s -- folder empty", f->name);
- X addstatus(str, true);
- X f = curflr;
- X }
- X }
- X else {
- X addstatus("internal error: folder unexpectedly valid!", true);
- X to_normal();
- X exit(0);
- X }
- X
- X alternate = (folder) NULL;
- X curflr = f;
- X curmail = f->mail;
- X y = FIRST;
- X display_page();
- X}
- END_OF_refresh.c
- if test 1896 -ne `wc -c <refresh.c`; then
- echo shar: \"refresh.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 3\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-